3 use MediaWiki\Block\BlockManager
;
4 use MediaWiki\Block\DatabaseBlock
;
5 use MediaWiki\Block\SystemBlock
;
6 use MediaWiki\Config\ServiceOptions
;
7 use MediaWiki\MediaWikiServices
;
12 * @coversDefaultClass \MediaWiki\Block\BlockManager
14 class BlockManagerTest
extends MediaWikiTestCase
{
22 protected function setUp() {
25 $this->user
= $this->getTestUser()->getUser();
26 $this->sysopId
= $this->getTestSysop()->getUser()->getId();
27 $this->blockManagerConfig
= [
28 'wgApplyIpBlocksToXff' => true,
29 'wgCookieSetOnAutoblock' => true,
30 'wgCookieSetOnIpBlock' => true,
31 'wgDnsBlacklistUrls' => [],
32 'wgEnableDnsBlacklist' => true,
34 'wgProxyWhitelist' => [],
35 'wgSecretKey' => false,
36 'wgSoftBlockRanges' => [],
40 private function getBlockManager( $overrideConfig ) {
41 return new BlockManager(
42 ...$this->getBlockManagerConstructorArgs( $overrideConfig )
46 private function getBlockManagerConstructorArgs( $overrideConfig ) {
47 $blockManagerConfig = array_merge( $this->blockManagerConfig
, $overrideConfig );
48 $this->setMwGlobals( $blockManagerConfig );
49 $this->overrideMwServices();
52 BlockManager
::$constructorOptions,
53 MediaWikiServices
::getInstance()->getMainConfig()
56 $this->user
->getRequest()
61 * @dataProvider provideGetBlockFromCookieValue
62 * @covers ::getBlockFromCookieValue
63 * @covers ::shouldApplyCookieBlock
65 public function testGetBlockFromCookieValue( $options, $expected ) {
66 $blockManager = $this->getBlockManager( [
67 'wgCookieSetOnAutoblock' => true,
68 'wgCookieSetOnIpBlock' => true,
71 $block = new DatabaseBlock( array_merge( [
72 'address' => $options[ 'target' ] ?
: $this->user
,
73 'by' => $this->sysopId
,
74 ], $options[ 'blockOptions' ] ) );
77 $class = new ReflectionClass( BlockManager
::class );
78 $method = $class->getMethod( 'getBlockFromCookieValue' );
79 $method->setAccessible( true );
81 $user = $options[ 'loggedIn' ] ?
$this->user
: new User();
82 $user->getRequest()->setCookie( 'BlockID', $block->getCookieValue() );
84 $this->assertSame( $expected, (bool)$method->invoke(
93 public static function provideGetBlockFromCookieValue() {
95 'Autoblocking user block' => [
100 'enableAutoblock' => true
105 'Non-autoblocking user block' => [
109 'blockOptions' => [],
113 'IP block for anonymous user' => [
115 'target' => '127.0.0.1',
117 'blockOptions' => [],
121 'IP block for logged in user' => [
123 'target' => '127.0.0.1',
125 'blockOptions' => [],
129 'IP range block for anonymous user' => [
131 'target' => '127.0.0.0/8',
133 'blockOptions' => [],
141 * @dataProvider provideIsLocallyBlockedProxy
142 * @covers ::isLocallyBlockedProxy
144 public function testIsLocallyBlockedProxy( $proxyList, $expected ) {
145 $class = new ReflectionClass( BlockManager
::class );
146 $method = $class->getMethod( 'isLocallyBlockedProxy' );
147 $method->setAccessible( true );
149 $blockManager = $this->getBlockManager( [
150 'wgProxyList' => $proxyList
154 $this->assertSame( $expected, $method->invoke( $blockManager, $ip ) );
157 public static function provideIsLocallyBlockedProxy() {
159 'Proxy list is empty' => [ [], false ],
160 'Proxy list contains IP' => [ [ '1.2.3.4' ], true ],
161 'Proxy list contains IP as value' => [ [ 'test' => '1.2.3.4' ], true ],
162 'Proxy list contains range that covers IP' => [ [ '1.2.3.0/16' ], true ],
167 * @covers ::isLocallyBlockedProxy
169 public function testIsLocallyBlockedProxyDeprecated() {
172 $this->hideDeprecated(
173 'IP addresses in the keys of $wgProxyList (found the following IP ' .
174 'addresses in keys: ' . $proxy . ', please move them to values)'
177 $class = new ReflectionClass( BlockManager
::class );
178 $method = $class->getMethod( 'isLocallyBlockedProxy' );
179 $method->setAccessible( true );
181 $blockManager = $this->getBlockManager( [
182 'wgProxyList' => [ $proxy => 'test' ]
186 $this->assertSame( true, $method->invoke( $blockManager, $ip ) );
190 * @dataProvider provideIsDnsBlacklisted
191 * @covers ::isDnsBlacklisted
192 * @covers ::inDnsBlacklist
194 public function testIsDnsBlacklisted( $options, $expected ) {
195 $blockManagerConfig = [
196 'wgEnableDnsBlacklist' => true,
197 'wgDnsBlacklistUrls' => $options['blacklist'],
198 'wgProxyWhitelist' => $options['whitelist'],
201 $blockManager = $this->getMockBuilder( BlockManager
::class )
202 ->setConstructorArgs( $this->getBlockManagerConstructorArgs( $blockManagerConfig ) )
203 ->setMethods( [ 'checkHost' ] )
206 $blockManager->expects( $this->any() )
207 ->method( 'checkHost' )
208 ->will( $this->returnValueMap( [ [
209 $options['dnsblQuery'],
210 $options['dnsblResponse'],
215 $blockManager->isDnsBlacklisted( $options['ip'], $options['checkWhitelist'] )
219 public static function provideIsDnsBlacklisted() {
220 $dnsblFound = [ '127.0.0.2' ];
221 $dnsblNotFound = false;
223 'IP is blacklisted' => [
225 'blacklist' => [ 'dnsbl.test' ],
227 'dnsblQuery' => '1.0.0.127.dnsbl.test',
228 'dnsblResponse' => $dnsblFound,
230 'checkWhitelist' => false,
234 'IP is blacklisted; blacklist has key' => [
236 'blacklist' => [ [ 'dnsbl.test', 'key' ] ],
238 'dnsblQuery' => 'key.1.0.0.127.dnsbl.test',
239 'dnsblResponse' => $dnsblFound,
241 'checkWhitelist' => false,
245 'IP is blacklisted; blacklist is array' => [
247 'blacklist' => [ [ 'dnsbl.test' ] ],
249 'dnsblQuery' => '1.0.0.127.dnsbl.test',
250 'dnsblResponse' => $dnsblFound,
252 'checkWhitelist' => false,
256 'IP is not blacklisted' => [
258 'blacklist' => [ 'dnsbl.test' ],
260 'dnsblQuery' => '4.3.2.1.dnsbl.test',
261 'dnsblResponse' => $dnsblNotFound,
263 'checkWhitelist' => false,
267 'Blacklist is empty' => [
271 'dnsblQuery' => '1.0.0.127.dnsbl.test',
272 'dnsblResponse' => $dnsblFound,
274 'checkWhitelist' => false,
278 'IP is blacklisted and whitelisted; whitelist is not checked' => [
280 'blacklist' => [ 'dnsbl.test' ],
282 'dnsblQuery' => '1.0.0.127.dnsbl.test',
283 'dnsblResponse' => $dnsblFound,
284 'whitelist' => [ '127.0.0.1' ],
285 'checkWhitelist' => false,
289 'IP is blacklisted and whitelisted; whitelist is checked' => [
291 'blacklist' => [ 'dnsbl.test' ],
293 'dnsblQuery' => '1.0.0.127.dnsbl.test',
294 'dnsblResponse' => $dnsblFound,
295 'whitelist' => [ '127.0.0.1' ],
296 'checkWhitelist' => true,
304 * @covers ::getUniqueBlocks
306 public function testGetUniqueBlocks() {
309 $class = new ReflectionClass( BlockManager
::class );
310 $method = $class->getMethod( 'getUniqueBlocks' );
311 $method->setAccessible( true );
313 $blockManager = $this->getBlockManager( [] );
315 $block = $this->getMockBuilder( DatabaseBlock
::class )
316 ->setMethods( [ 'getId' ] )
318 $block->expects( $this->any() )
320 ->willReturn( $blockId );
322 $autoblock = $this->getMockBuilder( DatabaseBlock
::class )
323 ->setMethods( [ 'getParentBlockId', 'getType' ] )
325 $autoblock->expects( $this->any() )
326 ->method( 'getParentBlockId' )
327 ->willReturn( $blockId );
328 $autoblock->expects( $this->any() )
329 ->method( 'getType' )
330 ->willReturn( DatabaseBlock
::TYPE_AUTO
);
332 $blocks = [ $block, $block, $autoblock, new SystemBlock() ];
334 $this->assertSame( 2, count( $method->invoke( $blockManager, $blocks ) ) );
338 * @covers ::trackBlockWithCookie
339 * @dataProvider provideTrackBlockWithCookie
340 * @param bool $expectCookieSet
341 * @param bool $hasCookie
342 * @param bool $isBlocked
344 public function testTrackBlockWithCookie( $expectCookieSet, $hasCookie, $isBlocked ) {
346 $this->setMwGlobals( 'wgCookiePrefix', '' );
348 $request = new FauxRequest();
350 $request->setCookie( 'BlockID', 'the value does not matter' );
354 $block = $this->getMockBuilder( DatabaseBlock
::class )
355 ->setMethods( [ 'getType', 'getId' ] )
357 $block->method( 'getType' )
358 ->willReturn( DatabaseBlock
::TYPE_IP
);
359 $block->method( 'getId' )
360 ->willReturn( $blockID );
365 $user = $this->getMockBuilder( User
::class )
366 ->setMethods( [ 'getBlock', 'getRequest' ] )
368 $user->method( 'getBlock' )
369 ->willReturn( $block );
370 $user->method( 'getRequest' )
371 ->willReturn( $request );
372 /** @var User $user */
374 // Although the block cookie is set via DeferredUpdates, in command line mode updates are
375 // processed immediately
376 $blockManager = $this->getBlockManager( [] );
377 $blockManager->trackBlockWithCookie( $user );
379 /** @var FauxResponse $response */
380 $response = $request->response();
381 $this->assertCount( $expectCookieSet ?
1 : 0, $response->getCookies() );
382 $this->assertEquals( $expectCookieSet ?
$blockID : null, $response->getCookie( 'BlockID' ) );
385 public function provideTrackBlockWithCookie() {
387 // $expectCookieSet, $hasCookie, $isBlocked
388 [ false, false, false ],
389 [ false, true, false ],
390 [ true, false, true ],
391 [ false, true, true ],